package com.example.remoteassistance;

import android.media.MediaCodec;
import android.media.MediaFormat;
import android.util.Log;
import android.view.Surface;

import java.io.IOException;
import java.nio.ByteBuffer;

//视频解码器
public class VideoDecoder implements Runnable {

    private static final String TAG = "VideoDecoder";

    private static final long TIME_OUT = 10000;
    private MediaCodec mMediaCodec;

    private boolean isDecoding;

    private byte[] mData;

    public VideoDecoder(Surface surface, int width, int height) {
        //设置格式 H264
        MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, width, height);
        format.setInteger(MediaFormat.KEY_BIT_RATE, width * height);
        format.setInteger(MediaFormat.KEY_FRAME_RATE, 20);
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
        try {
            mMediaCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
        } catch (IOException e) {
            e.printStackTrace();
        }
        mMediaCodec.configure(format, surface, null, 0);
        mMediaCodec.start();
    }

    //启动解码
    public void start() {
        new Thread(this).start();
        isDecoding = true;
    }

    //停止解码
    public void stop() {
        isDecoding = false;
    }

    //销毁
    public void destroy() {
        if (mMediaCodec != null) {
            mMediaCodec.release();
        }
    }

    public void setData(byte[] data) {
        mData = data;
    }

    public byte[] getData() {
        return mData;
    }

    @Override
    public void run() {
        while (isDecoding) {
            byte[] data = getData();
            if (data != null && data.length != 0) {
                decodeData(getData());
            }
        }
        Log.d(TAG, "decode thread is ending");
    }

    //解码数据
    public void decodeData(byte[] bytes) {
        int inputBufferIndex = mMediaCodec.dequeueInputBuffer(TIME_OUT);
        if (inputBufferIndex >= 0) {
            ByteBuffer inputBuffer = mMediaCodec.getInputBuffer(inputBufferIndex);
            inputBuffer.clear();
            inputBuffer.put(bytes, 0, bytes.length);
            mMediaCodec.queueInputBuffer(inputBufferIndex, 0, bytes.length, System.currentTimeMillis(), 0);
        }
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, TIME_OUT);
        while (outputBufferIndex >= 0) {
            mMediaCodec.releaseOutputBuffer(outputBufferIndex, true);
            outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        }
    }
}
